#ifndef RPM_PRIV_H_
#define RPM_PRIV_H_

#define RPMFILE_DEFINED    1

#include <curl/curl.h>
#include "rpm_tags.h"

static char RPM_MAGIC[]= { 0355, 0253, 0356, 0333 };
static char HEADER_SECTION_MAGIC[] = { 0216, 0255, 0350, 0001 };

#ifdef __GNUC__
#define PACKED_STRUCT_ATTR __attribute__( ( __packed__ ) )
#else
#warning "Not being compiled with packed structures so we won't be able to read real RPM files."
#define PACKED_STRUCT_ATTR
#endif

/* An RPM file is made up of four sections,
 *
 * Lead
 * Signature record,
 * Header record, header index records and index values
 * Payload - an compressed cpio archive
 *
 * Reference:
 * http://refspecs.linux-foundation.org/LSB_3.2.0/LSB-Core-generic/LSB-Core-generic/pkgformat.html
 */

/* RPM leader. */
typedef struct {
    unsigned char magic[4];     /*"\355\253\356\333"*/
    unsigned char major, minor; /* 3,0 for LSB packages. */
    short type;                 /* 0=binary package, 1=source package. */
    short archnum;
    char name[66];              /* Package name. */
    short osnum;                /* Always 1 for LSB. */
    short signature_type;       /* Always 5 for LSB. */
    char reserved[16];
} PACKED_STRUCT_ATTR RpmLead;

/*
 * RPM header record
 */
typedef struct  {
    unsigned char magic[4];     /*"\216\255\350\001"*/
    unsigned char reserved[4];  /* All zeros. */
    uint32_t nindex;            /* Number of RpmHeaderIndexRecords. */
    uint32_t hsize;             /* Size of index values in bytes. */
} PACKED_STRUCT_ATTR RpmHeaderRecord;

/*
 * An index record.
 */
typedef struct
{
    RpmTag tag;                 /* ID for this record. */
    RpmHeaderElementType type;  /* Datatype for this record. */
    off_t offset;               /* Offset of data measured from end of the array of RpmHeaderIndexRecords. */
    uint32_t count;             /* Number of elements in this record. */
} PACKED_STRUCT_ATTR RpmHeaderIndexRecord;

/*
 *
 * Internal representation of the RPM file.
 *
 */
typedef struct
{
    CURL * curl;                /* Handle to CURL accessor. */

    int numSignatureEntries;                    /* Number of signature entries. */
    RpmHeaderIndexRecord * signatureEntries;    /* Pointer to signature entries. */
    void * signatureStore;                      /* Pointer to signature data. */

    int numHeaderEntries;                       /* Number of header entries. */
    RpmHeaderIndexRecord * headerEntries;       /* Pointer to header entry index records. */
    char * headerStore;                         /* Pointer to header store data. */

    off_t payloadOffset;                        /* Offset from start of file containing the cpio payload. */
} RpmPriv;

/**
 *  Contains information about an open RPM file.
 */
typedef struct
{
    RpmPriv * priv;
} RpmFile;

#endif /*RPM_PRIV_H_*/
